SMItemCost = { }

SMItemSource = { }

SMVendorItems = { }

SMAHItems = { }

SMCraftItems = { }


local listHerbReagent =  {
			"Peacebloom", "Silverleaf", "Earthroot",
			"Mageroyal", "Briarthorn", "Swiftthistle", "Bruiseweed", "Stranglekelp",
			"Wild Steelbloom", "Grave Moss", "Kingsblood", "Liferoot",
			"Fadeleaf", "Goldthorn", "Khadgar's Whiskers", "Wintersbite",
			"Firebloom", "Purple Lotus", "Arthas'Tears", "Sungrass", "Blindweed", "Ghost Mushroom", "Gromsblood",
			"Golden Sansam", "Dreamfoil", "Mountain Silversage", "Plaguebloom", "Icecap",
			"Ragveil", "Terocone", "Ancient Lichen", "Nightmare Vine", "Netherbloom", "Mana Thistle", "Dreaming Glory",
			"Icethorn", "Lichbloom", "Fire Leaf", "Fire Seed", "Tiger Lily", "Adder's Tongue", "Deadnettle", "Goldclover", "Talandra's Rose",
		}

local listPigments = {
		["Alabaster Pigment"] = { "Peacebloom", "Silverleaf", "Earthroot" },
		["Dusky Pigment"] = { "Mageroyal", "Briarthorn", "Swiftthistle", "Bruiseweed", "Stranglekelp"},
		["Verdant Pigment"] = { "Mageroyal", "Briarthorn", "Swiftthistle", "Bruiseweed", "Stranglekelp"},
		["Golden Pigment"] = { "Wild Steelbloom", "Grave Moss", "Kingsblood", "Liferoot" },
		["Burnt Pigment"] = { "Wild Steelbloom", "Grave Moss", "Kingsblood", "Liferoot" },
		["Emerald Pigment"] = { "Fadeleaf", "Goldthorn", "Khadgar's Whiskers", "Wintersbite" },
		["Indigo Pigment"] = { "Fadeleaf", "Goldthorn", "Khadgar's Whiskers", "Wintersbite" },
		["Violet Pigment"] = { "Firebloom", "Purple Lotus", "Arthas'Tears", "Sungrass", "Blindweed", "Ghost Mushroom", "Gromsblood" },
		["Ruby Pigment"] = { "Firebloom", "Purple Lotus", "Arthas'Tears", "Sungrass", "Blindweed", "Ghost Mushroom", "Gromsblood" },
		["Silvery Pigment"] = { "Golden Sansam", "Dreamfoil", "Mountain Silversage", "Plaguebloom", "Icecap" },
		["Sapphire Pigment"] = { "Golden Sansam", "Dreamfoil", "Mountain Silversage", "Plaguebloom", "Icecap" },
		["Nether Pigment"] = { "Ragveil", "Terocone", "Ancient Lichen", "Nightmare Vine", "Netherbloom", "Mana Thistle", "Dreaming Glory" },
		["Ebon Pigment"] = { "Ragveil", "Terocone", "Ancient Lichen", "Nightmare Vine", "Netherbloom", "Mana Thistle", "Dreaming Glory" },
		["Azure Pigment"] = { "Icethorn", "Lichbloom", "Fire Leaf", "Fire Seed", "Tiger Lily", "Adder's Tongue", "Deadnettle", "Goldclover", "Talandra's Rose" },
		["Icy Pigment"] = { "Icethorn", "Lichbloom", "Fire Leaf", "Fire Seed", "Tiger Lily", "Adder's Tongue", "Deadnettle", "Goldclover", "Talandra's Rose" },
	}
local listRarePigments = {
		["Verdant Pigment"] = { "Peacebloom", "Silverleaf", "Earthroot" },
		["Burnt Pigment"] = { "Wild Steelbloom", "Grave Moss", "Kingsblood", "Liferoot" },
		["Indigo Pigment"] = { "Fadeleaf", "Goldthorn", "Khadgar's Whiskers", "Wintersbite" },
		["Ruby Pigment"] = { "Firebloom", "Purple Lotus", "Arthas'Tears", "Sungrass", "Blindweed", "Ghost Mushroom", "Gromsblood" },
		["Sapphire Pigment"] = { "Golden Sansam", "Dreamfoil", "Mountain Silversage", "Plaguebloom", "Icecap" },
		["Ebon Pigment"] = { "Ragveil", "Terocone", "Ancient Lichen", "Nightmare Vine", "Netherbloom", "Mana Thistle", "Dreaming Glory" },
		["Icy Pigment"] = { "Icethorn", "Lichbloom", "Fire Leaf", "Fire Seed", "Tiger Lily", "Adder's Tongue", "Deadnettle", "Goldclover", "Talandra's Rose" },
	}

local function tcontains(table, name)
	for _, val in ipairs(table) do
		if val == name then return true end
	end
	return false
end

local function GetAmountString(copper)
	if not copper then return "nil" end

	local silver = copper / 100;  copper = copper % 100
	local gold = silver / 100;  silver = silver % 100

	local string = ""
	if (copper >= 1) then string = (" %dc"):format(copper)..string end
	if (silver >= 1) then string = (" %ds"):format(silver)..string end
	if (gold >= 1)   then string = (" %dg"):format(gold)..string end

	if string == "" then
		string = "0c";
	end

	return string;
--	return ("%dg %ds %dc"):format(copper / 100 / 100, (copper / 100) % 100, copper % 100)
end

local function isHerb(name)
	return tcontains(listHerbReagent, name)
end

local function isPigment(name)
	return listPigments[name] ~= nil
end

local function ShowPigmentOptions(pigment, indent)

	local list = listPigments[pigment]
	if not list then
		SMDEBUG(1, "No pigment: "..pigment.."!")
		return
	end
	local string = ""
	for i=1,#(list) do
		string = list[i]..", "..string
	end

	SMDEBUG(1, indent.."Pigment can be milled from one of: "..string)
end
--[[

Structure for SMVendorItems:

[item] := zone, cost,

Structure for SMAHItems:

[item] := list of (count, bid, buyout)

Strucutre for SMCraftItems::

[item] :=
	["needs"] := list of ( reagentname, quantity )
	["canmake"] = list of characters with the ability to make it

]]--

local function GetAmountString(copper)
	if not copper then return "nil" end

	local silver = copper / 100;  copper = copper % 100
	local gold = silver / 100;  silver = silver % 100

	local string = ""
	if (copper > 0) then string = (" %dc"):format(copper)..string end
	if (silver > 0) then string = (" %ds"):format(silver)..string end
	if (gold > 0)   then string = (" %dg"):format(gold)..string end

	return string;
--	return ("%dg %ds %dc"):format(copper / 100 / 100, (copper / 100) % 100, copper % 100)
end

function SMIsVendorItem(name)

	if SMVendorItems and SMVendorItems[name] then return true end
	return false;
end

function SMItemSource:GetVendorCost(item)

	SMDEBUG(4, "GetVendorCost("..(item or "nil")..")")
	local smallestcost = 999999999;
	local smallestcostZone = "UNKNOWN"

	if SMVendorItems and SMVendorItems[item] then
		for zone, cost in pairs(SMVendorItems[item]) do
			if cost < smallestcost then
				SMDEBUG(4,"Found smallest cost of "..(smallestcost or "nil").." in "..(smallestcostZone or "nil"))
				smallestcost = cost
				smallestcostZone = zone
			end
		end
	end
	if smallestcostZone == "UNKNOWN" then return nil, nil end
	return smallestcost, smallestcostZone
end


-- Item should be a plain string name, cost should be in copper
-- gotta figure out how to store numAvail
function SMItemSource:addVendorItem(item, zone, numAvail, cost)

	if not item then
		SMDEBUG(1, "Nil item - not adding")
		return
	end
	if not SMVendorItems then SMVendorItems = { } end
	if not SMVendorItems[item] then SMVendorItems[item] = { } end

	if SMVendorItems[item][zone] == cost then
		SMDEBUG(3, "Duplicate data found, not adding "..item..".")
		return
	end
	SMVendorItems[item][zone] = cost
	SMDEBUG(4, "Added item "..item.." in "..(zone or "nil").." @ "..GetAmountString(cost)..".")
end

function SMItemSource:ScanVendor()

	local numItems = GetMerchantNumItems();

	if numItems < 1 then
		SMDEBUG(1, "Failed to find any items on a vendor")
		return
	end

	local zone = GetZoneText()..":"..GetSubZoneText()
	for i = 1, numItems do
		local name, texture, price, quantity, numAvailable, isUsable, extendedCost = GetMerchantItemInfo(i)
		if (not name) then
			SMDEBUG(2, "Nil item skipped from vendor")
		else
			SMItemSource:addVendorItem(name, zone, numAvailable, price)
		end
	end
end

function SMItemSource:addCraftItem(item, reagentList)

	if not item then
		SMDEBUG(1, "Nil item - not adding")
		return
	end
	if not SMCraftItems then SMCraftItems = { } end

	SMCraftItems[item] = reagentList;
	if not reagentList then
		SMDEBUG(2, "Added or replaced item "..item.." with null reagent list")
	else
		SMDEBUG(4, "Added or replaced item "..item.." with actual reagent list")
	end

end

function SMItemSource:ScanCraft()

	local numSkills = GetNumTradeSkills();

	if numSkills < 1 then
		SMDEBUG(1, "Failed to find any skills to scan")
		return
	end

	for i = 1, numSkills do
		skillName, skillType, numAvailable, isExpanded, altVerb = GetTradeSkillInfo(i)

		if (skillType ~= "header") then

			if (not skillName) then
				SMDEBUG(2, "Nil item skipped from skill list")
			else
				local reagentList = { }
				local numReagents = GetTradeSkillNumReagents(i);
				local totalReagents = 0;
				for j=1, numReagents, 1 do
					local reagentName, reagentTexture, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(i, j);
					reagentList[reagentName] = reagentCount
					--SMDEBUG(2, indent.."Requires: "..(reagentCount or "nil").." of "..(reagentName or "nil")..".  You have "..(playerReagentCount or "nil"))
				end
				SMItemSource:addCraftItem(skillName, reagentList)
			end
		end
	end
end

function SMItemSource:CraftDetails(search, indent)

	--TODO: Some sort of endless loop is possible with this - put in a safety

	SMDEBUG(4, "Looking for a match with "..(search or "nil"))
	if not (indent) then indent = "" end

	indent = indent.."    "
	if (isHerb(search)) then
		SMDEBUG(1, indent..search.." is an herb")
		return
	end
	if (isPigment(search)) then
		ShowPigmentOptions(search, indent)
		return
	end
	local cost, zone = SMItemSource:GetVendorCost(search)
	if (cost) then
		SMDEBUG(1, indent..search.." -Vendor in "..zone.." for "..GetAmountString(cost))
		return
	end

	if SMCraftItems[search] then
		for reagent, count in pairs(SMCraftItems[search]) do
			SMDEBUG(2, indent.."Requires: "..(count or "nil").." of "..(reagent or "nil"))
			if (--[[reagentCount > playerReagentCount]]--
			true) then
				SMItemSource:CraftDetails(reagent, indent)
			end
		end
	else
		SMDEBUG(2, indent.."Don't know how to make or acquire "..search)

	end
end

function SMItemSource:CanIAcquire(search)

	if isHerb(search) or isPigment(search) or SMCraftItems[search] then return true end
	return false
end